home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / language / embedded / develop / libsrc11.arc / AUTOBAUD.C next >
Text File  |  1989-05-04  |  3KB  |  119 lines

  1. /*    autobaud.c 4.3        */
  2. /*F****************************************************************
  3.  
  4. FUNCTION NAME:    autobaud
  5.  
  6. ACTION:        Determines Baud Rate setting for SCI Baud register
  7.         given E clock and desired baud rate.
  8.  
  9. PARAMETERS:
  10.         E_clock: System clock speed (in 100 hz units).
  11.  
  12.         Baud_Rate: desired baud rate in the form of:
  13.  
  14.             Baud_Rate = baud * 16 / 100
  15.  
  16. RETURNS:    (unsigned)
  17.  
  18.         If autobaud was unsuccessful, 0xFFFF is returned.
  19.  
  20.         If autobaud was successful, then the high byte
  21.         of the unsigned is the per cent error for the
  22.         baud rate setting (0 to 10%).  The low byte
  23.         of the returned value is the value for the SCI
  24.         BAUD register.
  25.  
  26. *******************************************************************/
  27. #include <hc11/directives.h>
  28. #define    EXT_PRECISION    32768    /* extended precision baud rates */
  29.  
  30. SMALL
  31. unsigned autobaud ( E_clock, baud )
  32.     unsigned    E_clock, baud ;
  33.  
  34.     {
  35.     unsigned        try[2] ;
  36.     unsigned        best, save ;
  37.     unsigned short        i, j ;
  38.     unsigned        Error[4] ;
  39.     static unsigned        prescaler [4] = { 1, 3, 4, 13 } ;
  40.     unsigned        lng_E_clk[2] ;
  41.     unsigned        rem[4] ;
  42.     unsigned        temp[2] ;
  43.  
  44.     /* one hundred as a 32 bit number */
  45.     static unsigned        hundred[2] = { 0, 100 } ;
  46.  
  47.     best = 0xFFFF ;        /* initial value */
  48.  
  49.     lng_E_clk[0]  = 0 ;
  50.     lng_E_clk[1]  = E_clock ;
  51.  
  52.     if    (baud > EXT_PRECISION)
  53.         {
  54.         baud -= EXT_PRECISION ;
  55.  
  56.         /*    lng_E_clk *= 100    */
  57.         dmulu (lng_E_clk, hundred, lng_E_clk) ;
  58.         }
  59.  
  60.     for    (i = 0 ; i < 4 ; i++ )
  61.  
  62.         for    (j = 0 ; j < 8 ; j++ )
  63.  
  64.             {
  65.  
  66.     /*   try = (lng_E_clk) / (long) (prescaler[i] << j)    */
  67.  
  68.             temp[0] = 0 ;
  69.             temp[1] = prescaler[i] << j ;
  70.             ddivu ( lng_E_clk, temp, rem ) ;
  71.             try [0] = rem [2] ;
  72.             try [1] = rem [3] ;
  73.  
  74.             /* rem has the remainder... */
  75.  
  76.             /* calculate per cent Error */
  77.  
  78.             /* Error = (abs(try - baud) * 100) / baud */
  79.  
  80.             if    (try[0] == 0)
  81.                 {
  82.                 if    ((unsigned) try[1] > baud)
  83.                     try[1]  -= baud ;
  84.                 else
  85.                     try[1]  = baud - try[1] ;
  86.  
  87.                 dmulu (try, hundred, Error) ;
  88.                 temp[0] = 0 ;
  89.                 temp[1] = baud ;
  90.                 ddivu (Error, temp, Error) ;
  91.  
  92.         /*    Since first 2 words of Error has remainder    */
  93.         /*    and last 2 words has result of division        */
  94.         /*    Move the result into the first 2 words for    */
  95.         /*    ease of access.                    */
  96.                 Error [0] = Error [2] ;
  97.                 Error [1] = Error [3] ;
  98.  
  99.         /*    if not exact, set at least a one percent Error    */
  100.  
  101.                 if ((rem[0] | rem[1]) != 0)
  102.                     Error[1] += 1 ;
  103.  
  104.                 if ((Error[0] == 0) && (Error[1] <= 10))
  105.                     /* perhaps a new best... */
  106.                     if (best > Error[1])
  107.                         {
  108.                         best = Error[1] ;
  109.                         save = (i << 4) | j ;
  110.                         }
  111.                 }
  112.             }
  113.     if (best == 0xFFFF)
  114.         return (best) ;
  115.     else
  116.         return (best << 8 | save) ;
  117.  
  118.     }    /* end of autobaud */
  119.